<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Custom Tree Graph</title>
  </head>

  <body>
    <div id="mountNode"></div>
    <button id="download">点击下载图片</button>
    <script src="assets/hierarchy.js"></script>
    <script src="../build/g6.js"></script>
    <script src="../build/minimap.js"></script>
    <script src="./assets/jquery-3.2.1.min.js"></script>
    <style>
      .g6-minimap {
        position: absolute;
        right: 0;
        bottom: 0;
      }
    </style>
    <script>
      const COLLAPSE_ICON = function(x, y, r) {
        return [
          ['M', x, y],
          ['a', r, r, 0, 1, 0, r * 2, 0],
          ['a', r, r, 0, 1, 0, -r * 2, 0],
          ['M', x + 2, y],
          ['L', x + 2 * r - 2, y],
        ];
      };
      const EXPAND_ICON = function(x, y, r) {
        return [
          ['M', x, y],
          ['a', r, r, 0, 1, 0, r * 2, 0],
          ['a', r, r, 0, 1, 0, -r * 2, 0],
          ['M', x + 2, y],
          ['L', x + 2 * r - 2, y],
          ['M', x + r, y - r + 2],
          ['L', x + r, y + r - 2],
        ];
      };
      G6.registerNode(
        'tree-node',
        {
          drawShape(cfg, group) {
            const rect = group.addShape('rect', {
              attrs: {
                fill: '#fff',
                stroke: '#666',
              },
            });
            const content = cfg.id.replace(/(.{19})/g, '$1\n');
            const text = group.addShape('text', {
              attrs: {
                text: content,
                x: 0,
                y: 0,
                textAlign: 'left',
                textBaseline: 'middle',
                fill: '#666',
              },
            });
            const bbox = text.getBBox();
            const hasChildren = cfg.children && cfg.children.length > 0;
            if (hasChildren) {
              group.addShape('marker', {
                attrs: {
                  x: bbox.maxX + 6,
                  y: bbox.minX + bbox.height / 2 - 6,
                  r: 6,
                  symbol: COLLAPSE_ICON,
                  stroke: '#666',
                  lineWidth: 2,
                },
                className: 'collapse-icon',
              });
            }
            rect.attr({
              x: bbox.minX - 4,
              y: bbox.minY - 6,
              width: bbox.width + (hasChildren ? 26 : 8),
              height: bbox.height + 12,
            });
            return rect;
          },
        },
        'single-shape',
      );
      const minimap = new Minimap({
        size: [200, 150],
        type: 'delegate',
        delegateStyle: {
          fill: '#fff',
          stroke: '#666',
        },
      });
      const graph = new G6.TreeGraph({
        container: 'mountNode',
        width: 800,
        height: 600,
        plugins: [minimap],
        modes: {
          default: [
            {
              type: 'collapse-expand',
              onChange(item, collapsed) {
                const icon = item.get('group').findByClassName('collapse-icon');
                if (collapsed) {
                  icon.attr('symbol', EXPAND_ICON);
                } else {
                  icon.attr('symbol', COLLAPSE_ICON);
                }
              },
            },
            'drag-canvas',
            'zoom-canvas',
          ],
        },
        defaultNode: {
          shape: 'tree-node',
          anchorPoints: [
            [0, 0.5],
            [1, 0.5],
          ],
        },
        defaultEdge: {
          shape: 'cubic-horizontal',
          style: {
            stroke: '#A3B1BF',
          },
        },
        layout: data => {
          return Hierarchy.compactBox(data, {
            direction: 'LR',
            getId(d) {
              return d.id;
            },
            getHeight() {
              return 16;
            },
            getWidth() {
              return 16;
            },
            getVGap() {
              return 20;
            },
            getHGap() {
              return 80;
            },
          });
        },
      });
      $.getJSON('./assets/data/modeling-methods.json', data => {
        graph.data(data);
        graph.render();
        graph.fitView();
      });
      document.getElementById('download').addEventListener('click', () => {
        graph.downloadImage();
      });
    </script>
  </body>
</html>
